package com.mxpio.erp.inventory.controller;

import com.mxpio.erp.common.enums.InventoryEnums;
import com.mxpio.erp.common.inventory.entity.*;
import com.mxpio.erp.common.inventory.service.*;
import com.mxpio.erp.common.inventory.vo.InventoryExportVO;
import com.mxpioframework.common.exception.MBootException;
import com.mxpioframework.common.util.BeanReflectionUtils;
import com.mxpioframework.common.vo.Result;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.jpa.query.Operator;
import com.mxpioframework.jpa.query.Order;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;

@Tag(name = "InventoryController", description = "库存盘点主单接口")
@RestController
@RequestMapping("/erp/inventory/inventory/")
public class InventoryController {

    @Autowired
    private InventoryService inventoryService;
    @Autowired
    private InventoryItemService inventoryItemService;
    @Autowired
    private InventoryReviewService inventoryReviewService;


	@GetMapping("list")
    @Operation(summary = "盘点单列表", description = "获取盘点单列表（无分页）", method = "GET")
    public Result<List<Inventory>> list(@Parameter(description="查询参数") Criteria criteria) throws UnsupportedEncodingException {
        List<Inventory> inventories = inventoryService.list(Inventory.class, criteria);
        return Result.OK(inventories);
    }

    @GetMapping("page")
    @Operation(summary = "盘点单列表", description = "获取盘点单列表（分页）", method = "GET")
    public Result<Page<Inventory>> page(@Parameter(description="查询参数") Criteria criteria, @Parameter(description="每页条数")Integer pageSize, @Parameter(description="页号")Integer pageNo) throws UnsupportedEncodingException {
        Pageable page = PageRequest.of(pageNo-1, pageSize);
        Page<Inventory> inventoryPage = inventoryService.listPage(Inventory.class, page, criteria);
        return Result.OK(inventoryPage);
    }

    @GetMapping("list/{inventoryCode}")
    @Operation(summary = "根据inventoryCode获取盘点单", description = "根据inventoryCode获取盘点单", method = "GET")
    public Result<Inventory> getById(@Parameter(description="业务单号") @PathVariable(name = "inventoryCode", required = true) String inventoryCode) {
        Inventory inventoryServiceById = inventoryService.getById(Inventory.class, inventoryCode);
        return Result.OK(inventoryServiceById);
    }

    @RequestMapping("save")
    @Operation(summary = "保存盘点单(新增/修改)", description = "保存盘点单(新增/修改)")
    public Result<Inventory> save(@RequestBody Inventory inventory) {
        Result<Inventory> inventoryResult = null;
        try {
            inventoryResult = inventoryService.saveInventory(inventory);
        } catch (MBootException e) {
            return Result.error(e.getMessage());
        }
        return inventoryResult;//
    }


    @RequestMapping("saveInventoryItmes")
    @Operation(summary = "维护盘点单盘点任务", description = "维护盘点单盘点任务")
    public Result<Inventory> saveInventoryItmes(@RequestBody Inventory inventory) {
        return inventoryService.saveInventoryItmes(inventory);//
    }


    @GetMapping("submitInventory/{inventoryCode}")
    @Operation(summary = "根据inventoryCode提交盘点单", description = "根据inventoryCode提交盘点单", method = "GET")
    public Result<Inventory> submitInventory(@Parameter(description="业务单号") @PathVariable(name = "inventoryCode", required = true) String inventoryCode) {
        Inventory inventoryServiceById = inventoryService.getById(Inventory.class, inventoryCode);
        if (inventoryServiceById==null){
            return Result.error("未找到对应盘点单数据");
        }
        if (StringUtils.equals(inventoryServiceById.getInventoryStatus(),"关闭")){
            return Result.error("当前盘点单状态不允许提交");
        }
        Criteria c = Criteria.create().addCriterion("inventoryCode", Operator.EQ, inventoryCode);
        List<InventoryItem> items = inventoryItemService.list(InventoryItem.class, c);
        int count = 0;
        for (InventoryItem item : items) {
            if (item.getInventoryNum() != null) {
                count++;
            }
        }
        if (StringUtils.equals(inventoryServiceById.getInventoryRange(),InventoryEnums.InventoryRange.ALL.getStatusCode()) &&  items.size() != count) {
            return Result.error("当前存在未完成的盘点，无法提交");
        } else if (StringUtils.equals(inventoryServiceById.getInventoryRange(),InventoryEnums.InventoryRange.PART.getStatusCode()) && count*100/items.size() < inventoryServiceById.getInventoryPercentage()){
            return Result.error("当前盘点比例未达到要求，无法提交");
        }
        inventoryServiceById.setInventoryStatus(InventoryEnums.InventoryStatus.REVIEW.getStatusCode());
        inventoryService.update(inventoryServiceById);//更新数据状态
        return Result.OK(inventoryServiceById);
    }

    @DeleteMapping("remove/{inventoryCodes}")
    @Operation(summary = "根据bizNo删除盘点单", description = "删除盘点单", method = "DELETE")
    @Transactional(readOnly = false)
    public Result<?> remove(@Parameter(description="业务单号，多个单号用英文逗号分隔") @PathVariable(name = "inventoryCodes", required = true) String inventoryCodes) {
        String[] inventoryCode = inventoryCodes.split(",");
        for(String key : inventoryCode){
        	Criteria c = Criteria.create().addCriterion("inventoryCode", Operator.EQ, key);
        	inventoryItemService.removeBatch(InventoryItem.class, c);//
            inventoryReviewService.removeBatch(InventoryReview.class,c);
            inventoryService.delete(Inventory.class, key);
        }
        return Result.OK();
    }
    @PutMapping("print/{inventoryCode}")
    @Operation(summary = "打印盘点单", description = "打印盘点单", method = "PUT")
    public Result<Inventory> open(@Parameter(description="业务单号") @PathVariable(name = "inventoryCode", required = true) String inventoryCode) {
        Inventory inventory = inventoryService.getById(Inventory.class,inventoryCode);
        inventory.setInventoryStatus(InventoryEnums.InventoryStatus.READY.getStatusCode());
        return Result.OK(inventoryService.update(inventory));
    }

    @PutMapping("commit/{inventoryCode}")
    @Operation(summary = "提交盘点单", description = "提交盘点单", method = "PUT")
    public Result<Inventory> commit(@Parameter(description="业务单号") @PathVariable(name = "inventoryCode", required = true) String inventoryCode) {
        Inventory inventory = inventoryService.getById(Inventory.class,inventoryCode);
        if (!StringUtils.equals(inventory.getInventoryStatus(),InventoryEnums.InventoryStatus.CREATE.getStatusCode())){
            return Result.error("非开立状态不可提交");
        }
        inventory.setInventoryStatus(InventoryEnums.InventoryStatus.READY.getStatusCode());
        return Result.OK(inventoryService.update(inventory));
    }
    @RequestMapping("review/{inventoryCode}")
    @Operation(summary = "复核盘点单", description = "复核盘点单")
    public Result<Inventory> review(@Parameter(description="业务单号") @PathVariable(name = "inventoryCode", required = true) String inventoryCode,
                                    @Parameter(description="复核结果") @RequestBody InventoryReview inventoryReview) {
        return inventoryService.review(inventoryCode,inventoryReview);
    }

    @PutMapping("close/{inventoryCode}")
    @Operation(summary = "关闭盘点单", description = "关闭盘点单", method = "PUT")
    public Result<Inventory> close(@Parameter(description="业务单号") @PathVariable(name = "inventoryCode", required = true) String inventoryCode) {
        Inventory inventory = inventoryService.getById(Inventory.class,inventoryCode);
        if (!StringUtils.equals(inventory.getInventoryStatus(),InventoryEnums.InventoryStatus.READY.getStatusCode())&&
                !StringUtils.equals(inventory.getInventoryStatus(),InventoryEnums.InventoryStatus.REVIEW.getStatusCode())){
            return Result.error("仅待盘点、待复核状态的数据可以执行关闭操作，关闭后不可恢复。");
        }
        inventory.setInventoryStatus(InventoryEnums.InventoryStatus.CLOSED.getStatusCode());
        return Result.OK(inventoryService.update(inventory));
    }


    @GetMapping("export")
    @Operation(summary = "导出盘点单列表", description = "导出盘点单列表", method = "GET")
    public Result<List<InventoryExportVO>> exportToExcel(@Parameter(description="查询参数") Criteria criteria) {
        List<Inventory> inventories = inventoryService.list(Inventory.class, criteria);
        List<InventoryExportVO> exportVOList = new ArrayList<>();
        if (inventories.size()>0){
            for (Inventory inventory:inventories){
                Criteria c = Criteria.create().addCriterion("inventoryCode", Operator.EQ, inventory.getInventoryCode());
                c.addOrder(new Order("lineNo",false));//按lineno升序
                List<InventoryItem> items = inventoryItemService.list(InventoryItem.class, c);
                if (items.size()>0){
                    for (InventoryItem item:items){
                        InventoryExportVO exportVO = new InventoryExportVO();
                        BeanReflectionUtils.copyProperties(exportVO, inventory);//拷贝主表内容
                        BeanReflectionUtils.copyProperties(exportVO,item);//拷贝从表内容
                        exportVOList.add(exportVO);
                    }
                }
            }
        }
        return Result.OK(exportVOList);
    }
}
